/**
 * 树状选择器
 * @author rxliuli
 */
Vue.component('rx-select-tree', {
    name: 'RxSelectTree',
    props: {
        // 接收绑定参数
        value: [String, Number],
        // 输入框宽度
        width: String,
        // 选项数据
        options: {
            type: Array,
            required: true,
        },
        // 输入框占位符
        placeholder: {
            type: String,
            required: false,
            default: '请选择',
        },
        // 树节点配置选项
        props: {
            type: Object,
            required: false,
            default: () => ({
                parent: 'parentId',
                value: 'id',
                label: 'label',
                children: 'children',
            }),
        },
    },
    // 设置绑定参数
    model: {
        prop: 'value',
        event: 'selected',
    },
    computed: {
        // 是否为树状结构数据
        dataType() {
            const jsonStr = JSON.stringify(this.options)
            return jsonStr.includes(this.props.children)
        },
        // 若非树状结构，则转化为树状结构数据
        data() {
            return this.options
        },
    },
    watch: {
        labelModel(val) {
            if (!val) {
                this.valueModel = ''
            }
            this.$refs.tree.filter(val)
        },
        value(val) {
            this.labelModel = this.queryTree(this.data, val)
        },
    },
    data() {
        return {
            // 树状菜单显示状态
            showStatus: false,
            // 菜单宽度
            treeWidth: 'auto',
            // 输入框显示值
            labelModel: '',
            // 实际请求传值
            valueModel: '0',
        }
    },
    created() {
        // 检测输入框原有值并显示对应 label
        if (this.value) {
            this.labelModel = this.queryTree(this.data, this.value)
        }
        // 获取输入框宽度同步至树状菜单宽度
        this.$nextTick(() => {
            this.treeWidth = `${(this.width || this.$refs.input.$refs.input.clientWidth) - 24}px`
        })
    },
    methods: {
        // 单击节点
        onClickNode(node) {
            this.labelModel = node[this.props.label]
            this.valueModel = node[this.props.value]
            this.onCloseTree()
        },
        // 隐藏树状菜单
        onCloseTree() {
            this.$refs.popover.showPopper = false
        },
        // 显示时触发
        onShowPopover() {
            this.showStatus = true
            this.$refs.tree.filter(false)
        },
        // 隐藏时触发
        onHidePopover() {
            this.showStatus = false
            this.$emit('selected', this.valueModel)
        },
        // 树节点过滤方法
        filterNode(query, data) {
            if (!query) return true
            return data[this.props.label].indexOf(query) !== -1
        },
        // 搜索树状数据中的 ID
        queryTree(tree, id) {
            let stark = []
            stark = stark.concat(tree)
            while (stark.length) {
                const temp = stark.shift()
                if (temp[this.props.children]) {
                    stark = stark.concat(temp[this.props.children])
                }
                if (temp[this.props.value] === id) {
                    return temp[this.props.label]
                }
            }
            return ''
        },
    },
    template: `<el-popover
  ref="popover"
  placement="bottom-start"
  trigger="click"
  @show="onShowPopover"
  @hide="onHidePopover"
>
  <el-tree
    ref="tree"
    class="select-tree"
    highlight-current
    :style="'min-width: ' + treeWidth"
    :data="data"
    :props="props"
    :expand-on-click-node="false"
    :filter-node-method="filterNode"
    :default-expand-all="false"
    @node-click="onClickNode"
  >
  </el-tree>
  <el-input
    slot="reference"
    ref="input"
    v-model="labelModel"
    clearable
    :style="'width: ' + width + 'px'"
    :class="{ 'rotate': showStatus }"
    suffix-icon="el-icon-arrow-down"
    :placeholder="placeholder"
  >
  </el-input>
</el-popover>
    `,
})
